using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using FairyGUI;
using GamePackage;
using QFramework;
using UnityEngine;

namespace Bingo.FairyGUI
{
    public class FairyGUIManager : MonoBehaviour
    {

        public const string FUI_PACKAGE_DIR = "Assets/Bundles/FairyGUI/GamePackage";

        private Dictionary<string, IPanel> mAllUI = new Dictionary<string, IPanel>();

        private void Awake()
        {
            GRoot.inst.SetContentScaleFactor(1080, 1920, UIContentScaler.ScreenMatchMode.MatchHeight);
        }

        public IPanel OpenUI<T>(string uiBehaviourName, IUIData uiData = null, string assetBundleName = null) where T : UIBasePanel
        {
            IPanel retPanel = null;

            if (!mAllUI.TryGetValue(uiBehaviourName, out retPanel))
            {
                retPanel = CreateUI<T>(uiBehaviourName, uiData, assetBundleName);
            }
//            Debug.Log("------- _showLoading "+_showLoading);

            if(_showLoading)
                GRoot.inst.AddChildAt(((UIBasePanel)retPanel).GObject,0);
            else
            {
                GRoot.inst.AddChild(((UIBasePanel)retPanel).GObject);
            }

            retPanel.Open(uiData);
            retPanel.Show();
            HideLoading();
            return retPanel;
        } 
         
        

        public IPanel CreateUI<T>(string uiBehaviourName, IUIData uiData = null, string assetBundleName = null) where T : UIBasePanel
        {
            IPanel ui;

            if (mAllUI.TryGetValue(uiBehaviourName, out ui))
            {
                return ui;
            }

            ui = UIBasePanel.Load<T>(uiBehaviourName, assetBundleName);
            ui.PanelInfo = new UIPanelInfo { AssetBundleName = assetBundleName, Level = UILevel.Common, PanelName = uiBehaviourName };
            mAllUI.Add(uiBehaviourName, ui);
            ui.Init(uiData);
            return ui;
        }

        #region UnityCSharp Generic Support

        /// <summary>
        /// Create&ShowUI
        /// </summary>
        public T OpenUI<T>(IUIData uiData = null, string assetBundleName = null, string prefabName = null) where T : UIBasePanel
        {
            return OpenUI<T>(prefabName ?? GetUIBehaviourName<T>(), uiData, assetBundleName) as T;
        }

        public void ShowUI<T>() where T : UIBasePanel
        {
            ShowUI(GetUIBehaviourName<T>());
        }
        
       

        public void HideUI<T>() where T : UIBasePanel
        {
            HideUI(GetUIBehaviourName<T>());
        }

        public void CloseUI<T>() where T : UIBasePanel
        {
            CloseUI(GetUIBehaviourName<T>());
        }

        public T GetUI<T>() where T : UIBasePanel
        {
            return GetUI(GetUIBehaviourName<T>()) as T;
        }

        #endregion

        /// <summary>
        /// 命名空间对应名字的缓存
        /// </summary>
        private Dictionary<string, string> mFullname4UIBehaviourName = new Dictionary<string, string>();

        private string GetUIBehaviourName<T>() where T : UIBasePanel
        {
            var fullBehaviourName = typeof(T).ToString();
            string retValue = null;

            if (mFullname4UIBehaviourName.TryGetValue(fullBehaviourName, out retValue))
            {
            }
            else
            {
                var nameSplits = fullBehaviourName.Split('.');
                retValue = nameSplits[nameSplits.Length - 1];
                mFullname4UIBehaviourName.Add(fullBehaviourName, retValue);
            }

            return retValue;
        }

        /// <summary>
        /// 显示UIBehaiviour
        /// </summary>
        /// <param name="uiBehaviourName"></param>
        public void ShowUI(string uiBehaviourName)
        {
            IPanel iuiPanel = null;
            if (mAllUI.TryGetValue(uiBehaviourName, out iuiPanel))
            {
                iuiPanel.Show();
            }
        }
        
        public void ShowUI(string uiBehaviourName,IUIData uiData = null)
        {
            IPanel iuiPanel = null;
            if (mAllUI.TryGetValue(uiBehaviourName, out iuiPanel))
            {
                iuiPanel.Show();
            }
        }

        /// <summary>
        /// 隐藏UI
        /// </summary>
        /// <param name="uiBehaviourName"></param>
        public void HideUI(string uiBehaviourName)
        {
            IPanel iuiPanel = null;
            if (mAllUI.TryGetValue(uiBehaviourName, out iuiPanel))
            {
                iuiPanel.Hide();
                GRoot.inst.RemoveChild(((UIBasePanel)iuiPanel).GObject);
            }

        }

        /// <summary>
        /// 获取UIBehaviour
        /// </summary>
        /// <param name="uiBehaviourName"></param>
        /// <returns></returns>
        public UIBasePanel GetUI(string uiBehaviourName)
        {
            IPanel retIuiPanel = null;

            if (mAllUI.TryGetValue(uiBehaviourName, out retIuiPanel))
            {
                return retIuiPanel as UIBasePanel;
            }

            return null;
        }

        /// <summary>
        /// 关闭并卸载UI
        /// </summary>
        /// <param name="behaviourName"></param>
        public void CloseUI(string behaviourName)
        {
            IPanel behaviour = null;

            mAllUI.TryGetValue(behaviourName, out behaviour);

            if (null != behaviour)
            {
                behaviour.Close();
                mAllUI.Remove(behaviourName);
                ((UIBasePanel)behaviour).GObject.RemoveFromParent();
            }
        }
        
        private UI_UILoading _uiLoading;
        private bool _showLoading = false;

        public async Task ShowLoading()
        {
            _showLoading = true;
            string assetBundleName = UIConst.UI_PACKAGE;
            string panelName = "UILoading";

            if (_uiLoading == null)
            {
#if UNITY_EDITOR
                UIPackage.AddPackage($"{FairyGUIManager.FUI_PACKAGE_DIR}/{assetBundleName}");
#else
            AssetBundle assetBundle = (AssetBundle)Bingo.Facades.Resources.LoadSync(assetBundleName);
            UIPackage.AddPackage(assetBundle);
#endif
                GObject gObject = UIPackage.CreateObject(assetBundleName, panelName);
                _uiLoading = (UI_UILoading) gObject;
            }

            int count = GRoot.inst.GetChildren().Length;
            GRoot.inst.AddChildAt(_uiLoading,count);

            _uiLoading.m_AnimIn.Play();
            await Task.Delay(TimeSpan.FromSeconds(0.5f));
        }

        public async Task HideLoading()
        {
            if (_uiLoading != null && _showLoading)
            {
                _uiLoading.m_AnimOut.Play();
                await Task.Delay(TimeSpan.FromSeconds(0.5f));
                GRoot.inst.RemoveChild(_uiLoading);
                _showLoading = false;
            }
        }

    }
}